<?php
/**
 * XPHP Framework
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * @category	XPHP
 * @package		XPHP_Image
 * @author		XWEB Dev Team
 * @copyright	Copyright (c) 2010-2011 XWEB. (http://xweb.vn)
 * @license		http://xphp.xweb.vn/license.html     GNU GPL License
 * @version		$Id: Image.php 20109 2011-22-08 02:05:09 Mr.UBKey $
 */
define("JPG", 0);
define("GIF", 1);
define("PNG", 2);
define("BMP", 3);
define("JPG_QUALITY", 100);
define("PNG_QUALITY", 0);
/**
 * XPHP_Exception.
 *
 * @see XPHP_Exception
 */
require_once 'XPHP/Exception.php';
/**
 * Lớp mở rộng hỗ trợ việc xử lý ảnh
 *
 * @category	XPHP
 * @package		XPHP_Image
 * @author		Mr.UBKey
 * @link		http://xphp.xweb.vn/user_guide/xphp_image.html
 */
class XPHP_Image
{
    private $filename;
    private $image;
    private $data;
    private $copy;
    /**
     * @param $filename Tên file ảnh
     */
    function XPHP_Image ($filename)
    {
        if (! is_file($filename))
            throw new XPHP_Exception("File does not exist");
        $this->filename = $filename;
        $this->data = getimagesize($this->filename);
        switch ($this->data['mime']) {
            case 'image/pjpeg':
            case 'image/jpeg':
                $this->image = imagecreatefromjpeg($this->filename);
                break;
            case 'image/gif':
                $this->image = imagecreatefromgif($this->filename);
                break;
            case 'image/png':
                $this->image = imagecreatefrompng($this->filename);
                break;
            case 'image/x-ms-bmp':
                $this->image = imagecreatefromwbmp($this->filename);
                break;
            default:
                throw new XPHP_Exception("File format is not supported");
                break;
        }
    }
    /**
     * Tạo một bản copy từ bản gốc của ảnh
     */
    public function duplicate ()
    {
        if (! isset($this->image))
            throw new XPHP_Exception("No image loaded");
        $this->copy = $this->image;
    }
    /**
     * Resize bản sao của ảnh gốc
     * @param $wx Chiều rộng tối đa
     * @param $hx Chiều cao tối đa
     * @param $wm Chiều rộng tối thiểu
     * @param $hm Chiều cao tối thiểu
     */
    public function resize ($wx, $hx, $wm = 0, $hm = 0)
    {
        if (! isset($this->image))
            throw new XPHP_Exception("No image loaded");
        if ($wx != $wm && $hx != $hm && $wm != 0 && $hm != 0)
            throw new XPHP_Exception("Bad dimensions specified");
        $r = $this->data[0] / $this->data[1];
        $rx = $wx / $hx;
        if ($wm == 0 || $hm == 0)
            $rm = $rx;
        else
            $rm = $wm / $hm;
        $dx = 0;
        $dy = 0;
        $sx = 0;
        $sy = 0;
        $dw = 0;
        $dh = 0;
        $sw = 0;
        $sh = 0;
        $w = 0;
        $h = 0;
        if ($r > $rx && $r > $rm) {
            $w = $wx;
            $h = $hx;
            $sw = $this->data[1] * $rx;
            $sh = $this->data[1];
            $sx = ($this->data[0] - $sw) / 2;
            $dw = $wx;
            $dh = $hx;
        } elseif ($r < $rm && $r < $rx) {
            $w = $wx;
            $h = $hx;
            $sh = $this->data[0] / $rx;
            $sy = ($this->data[1] - $sh) / 2;
            $sw = $this->data[0];
            $dw = $wx;
            $dh = $hx;
        } elseif ($r >= $rx && $r <= $rm) {
            $w = $wx;
            $h = $wx / $r;
            $dw = $wx;
            $dh = $wx / $r;
            $sw = $this->data[0];
            $sh = $this->data[1];
        } elseif ($r <= $rx && $r >= $rm) {
            $w = $hx * $r;
            $h = $hx;
            $dw = $hx * $r;
            $dh = $hx;
            $sw = $this->data[0];
            $sh = $this->data[1];
        } else {
            throw new XPHP_Exception("Can't resize the image");
        }
        $this->copy = imagecreatetruecolor($w, $h);
        imagecopyresampled($this->copy, $this->image, $dx, $dy, $sx, $sy, $dw, 
        $dh, $sw, $sh);
        return true;
    }
    /**
     * Lưu bản sao của ảnh. Nếu không truyền vào tên file hệ thống sẽ tự ghi đè lên bản gốc
     * @param string $filename Tên file ảnh
     * @param define $type Kiểu ảnh JPG, GIF, PNG, BMP
     * @throws MF_Exception
     */
    public function save ($filename = false, $type = JPG)
    {
        if (! isset($this->copy))
            throw new XPHP_Exception("No copy to save");
        if (! $filename)
            $filename = $this->filename;
        switch ($type) {
            case GIF:
                imagegif($this->copy, $filename);
                return true;
                break;
            case PNG:
                imagepng($this->copy, $filename, PNG_QUALITY);
                return true;
                break;
            case BMP:
                imagewbmp($this->copy, $filename);
                return true;
                break;
            case JPG:
            default:
                imagejpeg($this->copy, $filename, JPG_QUALITY);
                return true;
                break;
        }
        throw new XPHP_Exception("Save failed");
    }
    /**
     * Chuyển đổi bản sao thành chuỗi và trả về chuỗi
     * @param string $type
     */
    public function getString ($type = JPG)
    {
        if (! isset($this->copy))
            throw new XPHP_Exception("No copy to return");
        $contents = ob_get_contents();
        if ($contents !== false)
            ob_clean();
        else
            ob_start();
        $this->show($type);
        $data = ob_get_contents();
        if ($contents !== false) {
            ob_clean();
            echo $contents;
        } else
            ob_end_clean();
        return $data;
    }
    /**
     * Hiển thị chuỗi được tạo ra bởi getString()
     * @param $type Kiểu của ảnh JPG, GIF, PNG, BMP mặc định là JPG
     */
    public function show ($type = JPG)
    {
        if (! isset($this->copy))
            throw new XPHP_Exception("No copy to show");
        switch ($type) {
            case GIF:
                imagegif($this->copy, null);
                return true;
                break;
            case PNG:
                imagepng($this->copy, null, PNG_QUALITY);
                return true;
                break;
            case BMP:
                imagewbmp($this->copy, null);
                return true;
                break;
            case JPG:
            default:
                imagejpeg($this->copy, null, JPG_QUALITY);
                return true;
                break;
        }
        throw new XPHP_Exception("Show failed");
    }
    public function __destruct ()
    {
        imagedestroy($this->image);
        imagedestroy($this->copy);
        $this->filename = null;
        $this->data = null;
    }
}